package cn.software.service.impl;


import cn.software.entity.Resource;
import cn.software.entity.Role;
import cn.software.entity.RoleResource;
import cn.software.entity.param.ResourceParam;
import cn.software.entity.param.RoleParam;
import cn.software.entity.param.RoleResourceParam;
import cn.software.entity.vo.ResourceVo;
import cn.software.mapper.ResourceMapper;
import cn.software.mapper.RoleMapper;
import cn.software.mapper.RoleResourceMapper;
import cn.software.mapper.UserMapper;
import cn.software.service.ResourceService;
import com.baomidou.mybatisplus.core.conditions.query.LambdaQueryWrapper;
import com.baomidou.mybatisplus.core.conditions.query.QueryWrapper;
import org.springframework.beans.BeanUtils;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;

import java.util.ArrayList;
import java.util.List;

/**
 * @Author gxy
 * @Date 2023/5/31 8:11
 * @PackageName:cn.software.service.Impl
 * @ClassName: ResourceServiceImpl
 */
@Service
public class ResourceServiceImpl implements ResourceService {

    @Autowired
    private ResourceMapper resourceMapper;
    @Autowired
    private RoleResourceMapper roleResourceMapper;
    @Autowired
    private RoleMapper roleMapper;
    @Autowired
    private UserMapper userMapper;


    @Override
    public boolean addResource(ResourceParam resourceParam) {
        Resource resource = transformResourceParamToResource(resourceParam);
        int insert = resourceMapper.insert(resource);
        return insert > 0;
    }

    @Override
    public boolean updateResource(ResourceParam resourceParam) {
        Resource resource = transformResourceParamToResource(resourceParam);
        int update = resourceMapper.updateById(resource);
        return update > 0;
    }

    @Override
    public boolean disableResource(ResourceParam resourceParam) {
        Resource resource = transformResourceParamToResource(resourceParam);
        resource.setIsDelete(1);
        int update = resourceMapper.updateById(resource);
        QueryWrapper<RoleResource> queryWrapper = new QueryWrapper<>();
        queryWrapper.eq("resource_id",resource.getId());
        roleResourceMapper.delete(queryWrapper);
        return update > 0;
    }

    @Override
    public boolean enableResource(ResourceParam resourceParam) {
        Resource resource = transformResourceParamToResource(resourceParam);
        resource.setIsDelete(0);
        int update = resourceMapper.updateById(resource);
        return update > 0;
    }

    @Override
    public boolean grantPermissions(RoleResourceParam roleResourceParam) {
        RoleResource roleResource = transformRoleResourceParamToRoleResource(roleResourceParam);
        int insert = roleResourceMapper.insert(roleResource);
        return insert > 0;
    }

    @Override
    public boolean deletePermissions(RoleResourceParam roleResourceParam) {
        RoleResource roleResource = transformRoleResourceParamToRoleResource(roleResourceParam);
        QueryWrapper<RoleResource> queryWrapper = new QueryWrapper<>();
        queryWrapper.eq("role_id", roleResourceParam.getRoleId());
        queryWrapper.eq("resource_id",roleResourceParam.getResourceId());
        int delete = roleResourceMapper.delete(queryWrapper);
        return delete > 0;
    }

    @Override
    public List<ResourceVo> getAllSource() {
        LambdaQueryWrapper<Resource> queryWrapper1 = new LambdaQueryWrapper<>();
        List<Resource> listResource = resourceMapper.selectList(queryWrapper1);
        List<ResourceVo> listResourceVo = new ArrayList<>();

        for(Resource resource:listResource){
            ResourceVo resourceVo = transfromResourceToResourceVo(resource);

            LambdaQueryWrapper<RoleResource> queryWrapper = new LambdaQueryWrapper<>();
            queryWrapper.eq(RoleResource::getResourceId,resource.getId());
            List<RoleResource> listRoleResource = roleResourceMapper.selectList(queryWrapper);

            List<Integer> role  = new ArrayList<>();
            for(RoleResource roleResource : listRoleResource){
                role.add(roleResource.getRoleId());
            }
            resourceVo.setRoles(role);
            listResourceVo.add(resourceVo);
        }
        return listResourceVo;
    }


    /**
     * 1、请求参数为role_id
     * 2、根据role_id 查询 role-resource 表 获取resource_id
     * 3、根据resource_id 查询resource 表 获取对应资源
     * 4、返回List<ResourceVo>
     * @param
     * @return
     */
    @Override
    public List<ResourceVo> getSourceToRole(Integer id) {
        QueryWrapper<RoleResource> queryWrapper = new QueryWrapper<>();
        queryWrapper.eq("role_id",id);
        List<RoleResource> resourceId = roleResourceMapper.selectList(queryWrapper);

        List<Resource> listResource = new ArrayList<>();
        List<ResourceVo> listResourceVo = new ArrayList<>();
        for(RoleResource roleResource : resourceId){
            Resource resource = resourceMapper.selectById(roleResource.getResourceId());
            ResourceVo resourceVo = transfromResourceToResourceVo(resource);

            LambdaQueryWrapper<RoleResource> queryWrapper1 = new LambdaQueryWrapper<>();
            queryWrapper1.eq(RoleResource::getResourceId,roleResource.getResourceId());
            List<RoleResource> listRoleResource = roleResourceMapper.selectList(queryWrapper1);

            List<Integer> role  = new ArrayList<>();
            for(RoleResource roles : listRoleResource){
                role.add(roles.getRoleId());
            }
            resourceVo.setRoles(role);
            listResourceVo.add(resourceVo);
        }

        return listResourceVo;
    }




    @Override
    public boolean deleteResource(Integer id) {
        //删除资源对应的权限
        LambdaQueryWrapper<RoleResource> queryWrapper = new LambdaQueryWrapper<>();
        queryWrapper.eq(RoleResource::getResourceId,id);
        int deleteRoleResource = roleResourceMapper.delete(queryWrapper);
        System.out.println(deleteRoleResource);
        //删除资源
        int delete = resourceMapper.deleteById(id);

        return delete > 0;
    }

    private Resource transformResourceParamToResource(ResourceParam resourceParam) {
        Resource resource = new Resource();
        BeanUtils.copyProperties(resourceParam, resource);
        return resource;
    }


    private RoleResource transformRoleResourceParamToRoleResource(RoleResourceParam roleResourceParam) {
        RoleResource roleResource = new RoleResource();
        BeanUtils.copyProperties(roleResourceParam, roleResource);
        return roleResource;
    }

    private ResourceVo transfromResourceToResourceVo(Resource resource){
        ResourceVo resourceVo = new ResourceVo();
        BeanUtils.copyProperties(resource, resourceVo);
        return resourceVo;
    }

}
